import { deepCopy, messages } from "share/common";
/**
 * Created By ZaraNengap on 2017/09/21
 *
 * 2018/11/26 zaranengap
 * 这个项目为啥感觉很单一、不好看
 * 80%是因为这个东西
 * 这个东西你几乎可以在项目所有页面找到他
 * 这货就是个展示页面放到了弹窗里让你选
 * 感觉很万能，但是总感觉用着和看着不那么爽
 * 可惜已经成了项目主组件
 * damn
 *
 */
import React from "react";
import { connect } from "react-redux";
import { Form, Modal, message, Button, Tag, Icon } from "antd";
import ResizeTable from "components/resize-table";
import httpFetch from "share/httpFetch";
import SearchArea from "components/search-area";
import errorMessage from "share/errorMessage";
import Condition from "components/condition";
import config from "config";

/**
 * 联动static/chooserData.js文件
 * 该文件内存储各选择的页面渲染选项
 * 包括title、url、searchForm、columns、key
 * @params title  显示在页面上方的标题
 * @params url  获得数据的接口
 * @params searchForm  联动searchForm组件的参数，配置顶部搜索区域搜索项
 * @params columns  表格列配置
 * @params key  数据主键
 * @params listKey  列表在接口返回值内的变量名，如果接口直接返回数组则置空
 */
import chooserData from "share/chooserData";
const { If } = Condition;
const { FilterTags } = SearchArea;

/**
 * 通用表格选择器组件
 * @params visible  是否可见，同Modal
 * @params onOk  点击OK后的方法，同Modal
 * @params onCancel  点击取消后的方法，同Modal
 * @params afterClose  关闭窗口后的方法，同Modal
 * @params type  选择器类型，配置在chooserData内
 * @params selectedData  默认选择的值，如果一个页面由多个ListSelector配置，则不同的选择项应该在后续多次选择时传入对应的选择项
 * @params extraParams  搜索时额外需要的参数,如果对象内含有组件内存在的变量将替换组件内部的数值
 * @params selectorItem  组件查询的对象，如果存在普通配置没法实现的可单独传入，例如参数在url中间动态变换时，表单项需要参数搜索时
 * @params single 是否单选,默认为false
 * @params method 调用方法get/post
 * @params selectAll 是否需要选择全部按钮
 * @params selectAllLoading 全选全部按钮loading
 * @params onSelectAll 点击选择全部时的回调
 * @params maxNum 最多选择多少条数据
 * @params showDetail 是否在界面显示Tag已选项
 * @params showArrow 是否在Tag中显示箭头
 * @params additionalDefault 默认标签，在选项之外
 *
 * type与selectorItem可共存，如果两者都有，selectorItem起作用
 *
 * 现在支持的选择方法见share/chooserData.js
 */
class ListSelector extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: true,
      data: [],
      page: 0,
      pageSize: 10,
      pagination: {
        total: 0,
        showSizeChanger: true,
        pageSizeOptions: ["10", "50", "100"],
      },
      selectedData: [], // 已经选择的数据项
      selectorItem: {}, // 当前的选择器类型数据项, 包含url、searchForm、columns
      searchParams: {}, // 搜索需要的参数
      rowSelection: {
        type: props.single ? "radio" : "checkbox",
        selectedRowKeys: [],
        onChange: this.onSelectChange,
        onSelect: this.onSelectItem,
        onSelectAll: this
          .onSelectAll /*,
        getCheckboxProps: record => {
          const {additionalDefault = []} = this.props;
          return {
            disabled: record.userOID && additionalDefault.indexOf(record.userOID) > -1
          };
        } */,
      },
      filterItems: [],
      currentFilter: 0,
    };
  }

  search = (params) => {
    const { filterSearchParams } = this.props;
    const { selectorItem } = this.state;
    filterSearchParams && (params = filterSearchParams(params));
    if (params.vnlgnm) {
      params = {
        keyword: params.vnlgnm
      }
    }
    const filterItem = FilterTags.getFilterItem(
      selectorItem.searchForm,
      params
    );
    this.setState(
      {
        page: 0,
        filterItems: filterItem,
        searchParams: params,
        loading: true,
      },
      () => {
        this.getList();
      }
    );
  };

  clear = () => {
    const searchParams = {};
    this.state.selectorItem.searchForm.map((form) => {
      if (
        form.type === "select" &&
        form.defaultValue &&
        form.defaultValue.key
      ) {
        searchParams[form.id] = form.defaultValue.key;
      } else {
        searchParams[form.id] = form.defaultValue;
      }
    });
    this.setState(
      {
        page: 0,
        filterItems: [],
        searchParams,
      },
      () => {
        this.getList();
      }
    );
  };

  getDataLabel(data, keys) {
    const lenth = keys.split(".").length;
    keys &&
      keys.split(".").map((key, index) => {
        if (lenth - 1 !== index) {
          data = data[key];
        }
      });
    return data;
  }

  getLastKey = (key) => {
    if (key === 'mcd_car') {
      return 'carNumber'
    }
    return key.split(".")[key.split(".").length - 1];
  };
  //得到数据
  getList() {
    //
    const { reportId } = this.props;
    let selectorItem = this.state.selectorItem;
    let searchParams = Object.assign(
      {},
      this.state.searchParams,
      this.props.extraParams
    );
    let url = selectorItem.url;
    let reportIdParams = reportId ? `&reportId=${reportId}`  : '';
    let reg = /\?+/;
    if (reg.test(url)) {
      //检测是否已经有参数了，如果有直接加&
      url = `${selectorItem.url}&page=${this.state.page}&size=${this.state.pageSize}${reportIdParams}`;
    }else {
      url = `${selectorItem.url}?page=${this.state.page}&size=${this.state.pageSize}${reportIdParams}`;
    }
    this.setState({ loading: true });
    return httpFetch[this.props.method](url, searchParams)
      .then((response) => {
        let data = [];
        if (selectorItem.isValue) {
          response.data.map((item) => {
            const option = {};
            option[this.getLastKey(selectorItem.key)] = item;
            data.push(option);
          });
        } else {
          data = selectorItem.listKey
            ? response.data[selectorItem.listKey]
            : selectorItem.isValueList
            ? response.data.values
            : response.data;
        }
        const tmpData = [];
        data.map((item) => {
          tmpData.push(this.getDataLabel(item, selectorItem.key));
        });
        data = tmpData;
        data.map((item) => {
          item.key = item[this.getLastKey(selectorItem.key)];
        });
        const pagination = {
          total: Number(response.headers["x-total-count"]),
          showSizeChanger: true,
          onShowSizeChange: this.onChangePagerSize,
          onChange: this.onChangePager,
          current: this.state.page + 1,
          pageSize: this.state.pageSize,
          pageSizeOptions: ["10", "50", "100"],
        };
        if (
          !Number(response.headers["x-total-count"]) &&
          typeof selectorItem.listKey !== "undefined"
        ) {
          pagination.total =
            response.data.total || response.data[selectorItem.listKey].length;
        }
        this.setState(
          {
            data,
            loading: false,
            pagination,
          },
          () => {
            this.refreshSelected(); // 刷新当页选择器
          }
        );
      })
      .catch((e) => {
        if (config.appEnv === "dev") {
          console.error("获取数据失败，请稍后重试或联系管理员", e);
        }
        const pagination = {
          total: 0,
          showSizeChanger: true,
          onShowSizeChange: this.onChangePagerSize,
          onChange: this.onChangePager,
          current: 1,
          pageSize: this.state.pageSize,
          pageSizeOptions: ["10", "50", "100"],
        };
        this.setState(
          {
            data: [],
            loading: false,
            pagination,
          },
          () => {
            this.refreshSelected(); // 刷新当页选择器
          }
        );
        // '获取数据失败，请稍后重试或联系管理员'
        errorMessage(e.response, messages("common.error1"));
        this.setState({ loading: false });
      });
  }

  onChangePager = (page) => {
    if (page - 1 !== this.state.page) {
      this.setState(
        {
          page: page - 1,
          loading: true,
        },
        () => {
          this.getList();
        }
      );
    }
  };

  onChangePagerSize = (current, size) => {
    if (size !== this.state.pageSize) {
      this.setState(
        {
          page: 0,
          pageSize: size,
          loading: true,
        },
        () => {
          this.getList();
        }
      );
    }
  };

  /**
   * 判断this.props.type是否有变化，如果有变化则重新渲染页面
   * @param type
   */
  checkType(type) {
    const selectorItem = chooserData[type];
    if (selectorItem) {
      this.checkSelectorItem(selectorItem);
    } else {
      console.error(`未定义的chooserData：${type}`);
    }
  }

  checkSelectorItem(selectorItem) {
    let searchParams = {};
    selectorItem.searchForm.map((form) => {
      searchParams[form.id] = form.defaultValue; // 遍历searchForm，取id组装成searchParams
      if (
        form.type === "select" &&
        form.defaultValue &&
        form.defaultValue.key
      ) {
        searchParams[form.id] = form.defaultValue.key;
      }
    });
    if (JSON.stringify(this.state.searchParams) !== "{}") {
      searchParams = this.state.searchParams;
    }
    this.setState({ selectorItem, searchParams }, () => {
      this.getList();
    });
  }

  /**
   * @description 获取子组件的方法
   */

  componentDidMount() {
    this.props.modalRef && this.props.modalRef(this);
  }

  /**
   * 每次父元素进行setState时调用的操作，判断nextProps内是否有type的变化
   * 如果selectedData有值则代表有默认值传入需要替换本地已选择数组，
   * 如果没有值则需要把本地已选择数组置空
   * @param nextProps 下一阶段的props
   */
  componentWillReceiveProps = (nextProps) => {
    if (
      nextProps.visible === this.props.visible &&
      !(
        this.props.selectAllHolding &&
        this.props.selectAllLoading &&
        !nextProps.selectAllLoading
      )
    ) {
      return;
    }
    if (!nextProps.visible && this.props.visible) {
      // 关闭Modal不需要再次查list数据
      this.formRef && this.formRef.clearSearchAreaSelectData();
      this.clear();
    }
    this.setState({ page: 0 });
    if (nextProps.selectedData && nextProps.selectedData.length > 0) {
      this.setState({ selectedData: nextProps.selectedData });
    } else {
      this.setState({ selectedData: [] });
    }
    if (
      nextProps.type !== this.state.type &&
      !nextProps.selectorItem &&
      nextProps.visible
    ) {
      this.checkType(nextProps.type);
    } else if (nextProps.selectorItem && nextProps.visible)
      this.checkSelectorItem(nextProps.selectorItem);

    const { rowSelection } = this.state;
    rowSelection.selectedRowKeys = [];
    if (nextProps.single !== (rowSelection.type === "radio")) {
      rowSelection.type = nextProps.single ? "radio" : "checkbox";
    }
    this.setState({ rowSelection });
  };

  handleOk = () => {
    this.setState(
      {
        filterItems: [],
      },
      () => {
        this.props.onOk({
          result: this.state.selectedData,
          type: this.props.type,
        });
      }
    );
  };

  /**
   * 根据selectedData刷新当页selection
   */
  refreshSelected() {
    const { valueKey } = this.props;
    const { selectorItem, selectedData, data, rowSelection } = this.state;
    const nowSelectedRowKeys = [];
    selectedData.map((selected) => {
      data.map((item) => {
        if (
          item[this.getLastKey(valueKey || selectorItem.key)] ==
          selected[this.getLastKey(valueKey || selectorItem.key)]
        ) {
          nowSelectedRowKeys.push(item[this.getLastKey(selectorItem.key)]);
        }
      });
    });
    rowSelection.selectedRowKeys = nowSelectedRowKeys;
    this.setState({ rowSelection });
  }

  //选项改变时的回调，重置selection
  onSelectChange = (selectedRowKeys, selectedRows) => {
    const { rowSelection } = this.state;
    if (
      !(
        this.props.maxNum &&
        this.props.maxNum > 0 &&
        selectedRowKeys.length > this.props.maxNum
      )
    ) {
      rowSelection.selectedRowKeys = selectedRowKeys;
    }
    this.setState({ rowSelection });
  };

  /**
   * 选择单个时的方法，遍历selectedData，根据是否选中进行插入或删除操作
   * @param record 被改变的项
   * @param selected 是否选中
   */
  onSelectItem = (record, selected) => {
    const { valueKey } = this.props;
    let { selectedData, selectorItem } = this.state;
    if (this.props.single) {
      selectedData = [record];
    } else {
      const key = this.getLastKey(valueKey || selectorItem.key);
      if (!selected) {
        selectedData.map((selected, index) => {
          if (selected[key] == record[key]) {
            selectedData.splice(index, 1);
          }
        });
      } else if (
        this.props.maxNum &&
        this.props.maxNum > 0 &&
        selectedData.length >= this.props.maxNum
      ) {
        message.warning(
          messages("common.max.selected.data", { max: this.props.maxNum })
        );
      } else {
        selectedData.push(record);
      }
    }
    this.setState({ selectedData });
  };

  // 点击行时的方法，遍历遍历selectedData，根据是否选中进行遍历遍历selectedData和rowSelection的插入或删除操作
  handleRowClick = (record) => {
    const { valueKey, noValueError, additionalDefault = [] } = this.props;
    // valueKey 没有时下面这一行报错 例如切换公司模式
    if (valueKey && !record[this.getLastKey(valueKey)]) {
      message.error(noValueError);
      return;
    }
    let { selectedData, selectorItem, rowSelection } = this.state;
    if (this.props.single) {
      selectedData = [record];
      rowSelection.selectedRowKeys = [
        record[this.getLastKey(selectorItem.key)],
      ];
    } else {
      let haveIt = false;
      const theKey = this.getLastKey(valueKey || selectorItem.key);
      // if(additionalDefault.indexOf(record[theKey]) === -1) {
      selectedData.map((selected, index) => {
        if (selected[theKey] === record[theKey]) {
          selectedData.splice(index, 1);
          haveIt = true;
        }
      });
      if (!haveIt) {
        if (
          this.props.maxNum &&
          this.props.maxNum > 0 &&
          selectedData.length >= this.props.maxNum
        ) {
          message.warning(
            messages("common.max.selected.data", { max: this.props.maxNum })
          );
        } else {
          selectedData.push(record);
          rowSelection.selectedRowKeys.push(
            record[this.getLastKey(selectorItem.key)]
          );
        }
      } else {
        rowSelection.selectedRowKeys.map((item, index) => {
          if (`${item}` === `${record[this.getLastKey(selectorItem.key)]}`) {
            rowSelection.selectedRowKeys.splice(index, 1);
          }
        });
      }
      // }
    }
    this.setState({ selectedData, rowSelection });
  };

  // 选择当页全部时的判断
  onSelectAll = (selected, selectedRows, changeRows) => {
    if (
      this.props.maxNum &&
      this.props.maxNum > 0 &&
      changeRows.length + this.state.selectedData.length > this.props.maxNum &&
      selected
    ) {
      message.warning(
        messages("common.max.selected.data", { max: this.props.maxNum })
      );
    } else {
      changeRows.map((changeRow) => this.onSelectItem(changeRow, selected));
    }
  };

  closeTag = (e, record, key) => {
    e.preventDefault();
    // const {additionalDefault = []} = this.props;
    // if(additionalDefault.indexOf(key) > -1) return;
    this.handleRowClick(record);
  };

  handleCloseFilterTag = (removedTag) => {
    const { filterItems, searchParams } = this.state;
    const filter = filterItems.filter((tag) => tag.id !== removedTag.id);
    const params = deepCopy(searchParams);
    params[removedTag.id] = null;
    this.setState(
      {
        filterItems: filter,
        searchParams: params,
      },
      () => this.getList()
    );
  };

  handleToggleFilterTag = (removedTag) => {
    const { filterItems, searchParams } = this.state;
    const params = deepCopy(searchParams);
    if (removedTag.checked) {
      params[removedTag.id] = null;
    } else {
      params[removedTag.id] = removedTag.valueOid;
    }
    const filter = filterItems.map((tag) => {
      tag.id === removedTag.id && (tag.checked = !tag.checked);
      return tag;
    });
    this.setState(
      {
        page: 0,
        filterItems: filter,
        searchParams: params,
      },
      () => this.getList()
    );
  };

  handleClose = () => {
    this.setState(
      {
        filterItems: [],
      },
      this.props.onCancel
    );
  };

  render() {
    const {
      visible,
      onCancel,
      afterClose,
      selectAll,
      selectAllLoading,
      onSelectAll,
      hidePagination,
      showDetail,
      labelKey,
      showArrow,
      additionalDefault = [],
      valueKey,
      confirmLoading,
      locale,
      beforeTable,
      eventHandle,
    } = this.props;
    const {
      data,
      pagination,
      loading,
      selectorItem,
      selectedData,
      rowSelection,
      filterItems,
    } = this.state;
    const { searchForm, columns, title, key } = selectorItem;
    const localeAttr = locale ? { locale } : {};
    return (
      <Modal
        title={title}
        visible={visible}
        onCancel={this.handleClose}
        afterClose={afterClose}
        width={800}
        onOk={this.handleOk}
        confirmLoading={confirmLoading}
        className="list-selector"
      >
        {searchForm && searchForm.length > 0 && (
          <SearchArea
            searchForm={searchForm}
            isReturnLabel
            submitHandle={this.search}
            clearHandle={this.clear}
            collapsible
            wrappedComponentRef={(inst) => (this.formRef = inst)}
            eventHandle={eventHandle}
          />
        )}
        {showDetail && (
          <div className="selected-tag">
            {selectedData.map((item, index) => (
              <span key={item[this.getLastKey(valueKey || key)]}>
                <Tag closable onClick={(e) => this.closeTag(e, item)}>
                  {item[labelKey]}
                </Tag>
                {showArrow && index !== selectedData.length - 1 && (
                  <Icon type="arrow-right" style={{ marginRight: 8 }} />
                )}
              </span>
            ))}
          </div>
        )}
        {beforeTable}
        {!hidePagination && (
          <div className="table-header">
            <div className="table-header-title f-left">
              {selectAll && (
                <Button
                  style={{ marginRight: 10 }}
                  loading={selectAllLoading}
                  onClick={onSelectAll}
                  type="primary"
                >
                  {messages("common.selectAll") /*选择全部*/}
                </Button>
              )}
              {messages("common.total", {
                total: pagination.total || data.length,
              })}
              {/* 共 total 条数据 */}
              &nbsp;<span>/</span>&nbsp;
              {messages("common.total.selected", {
                total: selectedData.length === 0 ? "0" : selectedData.length,
              })}
              {/* 已选 total 条 */}
            </div>
          </div>
        )}
        <If value={filterItems.filter((f) => f.value).length}>
          <FilterTags
            filterItems={filterItems}
            onCloseTag={this.handleCloseFilterTag}
            onToggleTag={this.handleToggleFilterTag}
          />
        </If>
        <ResizeTable
          columns={columns}
          onRow={(record) => ({ onClick: () => this.handleRowClick(record) })}
          dataSource={data}
          rowKey={(record) => record[this.getLastKey(key)]}
          pagination={hidePagination ? false : pagination}
          loading={loading}
          hideScroll={!!hidePagination}
          rowClassName="chooser-table-row"
          bordered
          size="small"
          {...localeAttr}
          rowSelection={rowSelection}
        />
        {this.props.extraBottom}
      </Modal>
    );
  }
}

ListSelector.propTypes = {
  visible: React.PropTypes.bool, // 对话框是否可见
  onOk: React.PropTypes.func, // 点击OK后的回调，当有选择的值时会返回一个数组
  onCancel: React.PropTypes.func, // 点击取消后的回调
  afterClose: React.PropTypes.func, // 关闭后的回调
  type: React.PropTypes.string, // 选择类型
  selectedData: React.PropTypes.array, // 默认选择的值id数组
  extraParams: React.PropTypes.object, // 搜索时额外需要的参数,如果对象内含有组件内存在的变量将替换组件内部的数值
  selectorItem: React.PropTypes.object, // 组件查询的对象，如果存在普通配置没法实现的可单独传入，例如参数在url中间动态变换时，表单项需要参数搜索时
  single: React.PropTypes.bool, // 是否单选
  method: React.PropTypes.string, // 调用方法get/post
  selectAll: React.PropTypes.bool, // 是否需要选择全部按钮
  selectAllLoading: React.PropTypes.bool, // 全选全部按钮loading
  selectAllHolding: React.PropTypes.bool, // 全选全部的时候不关闭窗口
  onSelectAll: React.PropTypes.func, // 点击选择全部时的回调
  maxNum: React.PropTypes.number, // 最多选择多少条数据
  showDetail: React.PropTypes.bool, // 是否在界面显示已选项
  labelKey: React.PropTypes.string, // Tag内显示的值
  showArrow: React.PropTypes.bool, // 是否在Tag中显示箭头
  additionalDefault: React.PropTypes.array, // 默认标签，在选项之外
  confirmLoading: React.PropTypes.bool, // 确定按钮的loading
  modalRef: React.PropTypes.func, // 获取子组件方法
  locale: React.PropTypes.object, // 默认文案设置，具体参考antd Table组件
  valueKey: React.PropTypes.string,
  hidePagination: React.PropTypes.bool,
  eventHandle: React.PropTypes.func, // 表单项点击事件
  filterSearchParams: React.PropTypes.func, // 处理搜索条件
  beforeTable: React.PropTypes.any,
};

ListSelector.defaultProps = {
  afterClose: () => {},
  extraParams: {},
  single: false,
  method: "get",
  selectAll: false,
  selectAllLoading: false,
  selectAllHolding: false,
  onSelectAll: () => {},
  showDetail: false,
  showArrow: false,
  additionalDefault: [],
  confirmLoading: false,
  noValueError: messages(
    "components.key724"
  ) /*该值必须值没有维护，请维护后重试。 */,
  eventHandle: () => {},
  beforeTable: null,
};

function mapStateToProps() {
  return {};
}

export default connect(mapStateToProps)(Form.create()(ListSelector));
